home *** CD-ROM | disk | FTP | other *** search
- /*
- cvcltree.cpp
-
- ClassTreeView--displays class hierarchy view
-
- C++/Views 2.0 Demo
- Copyright (c) 1992, by Liant Software Corp.
- ALL RIGHTS RESERVED.
-
- Revision History:
- -----------------
- */
-
- #include "cvcltree.h"
- #include "cvclinfo.h"
- #include "port.h"
- #include "brush.h"
- #include "font.h"
- #include "shade.h"
- #include "tagstrm.h"
-
- #include <stdio.h> // for sscanf()
-
- #define BOX_WIDTH 86
- #define BOX_HEIGHT 18
-
- defineClass(ClassTreeView, VView)
-
- ClassTreeView::ClassTreeView()
- {
- ;
- }
-
- ClassTreeView::ClassTreeView(VFrame &f, VWindow *parent)
- : VView(f, parent, StyleSizable)
- {
- firstClass = 0;
- lastClass = 0;
- currClass = 0;
-
- selectMthd = 0;
- client = 0;
-
- aPort = new VPort(this);
- aFont = new VFont("Arial", 8);
- aPort->useFont(aFont);
-
- setBackground(new VBrush(LightGray));
- }
-
- ClassTreeView::~ClassTreeView()
- {
- /* destroy background brush (if present) */
- delete getBackground();
-
- delete aPort;
- delete aFont;
-
- /* free list of classes */
- reset();
- }
-
- boolean ClassTreeView::free()
- {
- delete this;
- return(TRUE);
- }
-
- void ClassTreeView::reset()
- {
- ClassInfo *cinfo, *next;
-
- /* free list of classes */
- cinfo = firstClass;
- while(cinfo) {
- next = cinfo->getNext();
- delete cinfo;
- cinfo = next;
- }
-
- firstClass = 0;
- lastClass = 0;
- currClass = 0;
- }
-
- boolean ClassTreeView::loadFromStream(VStream &strm)
- /*
- Load a class tree from the description in 'strm':
-
- (object parent 40 250)
- */
- {
- VTagStream tagStrm;
- VString cmd;
- char name[60], parent[60];
- int x, y;
-
- reset();
- tagStrm.beginScan(&strm, NIL);
- tagStrm.tags('(', ')');
-
- while(tagStrm.getTag(cmd)) {
- sscanf(cmd.gets(), "%s %s %d %d", name, parent, &x, &y);
- add(name, parent, x, y);
- }
-
- return(TRUE);
- }
-
- void ClassTreeView::add(char *classname, char *parentname, int x, int y)
- /*
- Add a class to the class list
- */
- {
- ClassInfo *cinfo;
-
- if (!firstClass) {
- /* create list of classes */
- firstClass = new ClassInfo(classname, 0, x, y);
- lastClass = firstClass;
- }
- else {
- /* add new class to end of list */
- lastClass = new ClassInfo(classname, lastClass, x, y);
-
- /* find parent class */
- if (parentname) {
- for(cinfo = firstClass; cinfo != 0; cinfo = cinfo->getNext()) {
- if (*(cinfo->getName()) == parentname) {
- lastClass->setParent(cinfo);
- break;
- }
- }
- }
- }
- }
-
- boolean ClassTreeView::paint()
- /*
- Draw the class hierarchy view.
- */
- {
- ClassInfo *cinfo;
-
- aPort->open();
-
- /* draw the classes */
- for(cinfo = firstClass; cinfo != 0; cinfo = cinfo->getNext()) {
-
- /* draw connecting line to parent */
- if (cinfo->getParent()) {
- int xp = cinfo->getParent()->getX() + BOX_WIDTH / 2 + 1;
- int yp = cinfo->getParent()->getY();
- int xc = cinfo->getX() - BOX_WIDTH / 2;
- int yc = cinfo->getY();
- int xmid = (xc + xp) / 2;
-
- aPort->moveTo(xp, yp);
- aPort->lineTo(xmid, yp);
- aPort->lineTo(xmid, yc);
- aPort->lineTo(xc, yc);
- }
-
- /* draw boxes for the class */
- drawClass(cinfo, aPort);
- }
-
- aPort->close();
-
- return(TRUE);
- }
-
- void ClassTreeView::drawClass(ClassInfo *cinfo, VPort *port)
- /*
- Draw a single class button
- */
- {
- VRectangle rect;
-
- int xmin, ymin, xmax, ymax;
-
- xmin = cinfo->getX() - BOX_WIDTH / 2;
- ymin = cinfo->getY() - BOX_HEIGHT / 2;
- xmax = xmin + BOX_WIDTH;
- ymax = ymin + BOX_HEIGHT;
-
- VPen pn;
-
- port->usePen(&pn);
- port->useBrush(getBackground());
-
- pn.color(BLACK);
- rect.set(Corners, xmin - 1, ymin - 1, xmax + 2, ymax + 2);
- port->fillRegion(&rect);
-
- if (cinfo == currClass) {
- pn.color(DarkGray);
- port->moveTo(xmin, ymax);
- port->lineTo(xmax, ymax);
- port->lineTo(xmax, ymin);
- port->lineTo(xmin, ymin);
- port->lineTo(xmin, ymax);
-
- pn.color(LightGray);
- port->moveTo(xmin + 1, ymax - 1);
- port->lineTo(xmax - 1, ymax - 1);
- port->lineTo(xmax - 1, ymin + 1);
-
- /* draw dotted line to indicate selected item */
- // rect.set(CenterDim, cinfo->getX(), cinfo->getY(), BOX_WIDTH - 4, BOX_HEIGHT - 4);
- // pn.color(BLACK);
- // pn.pattern(DotLine);
- // port->frameRegion(&rect);
-
-
- rect.set(CenterDim, cinfo->getX() + 1, cinfo->getY() + 2, BOX_WIDTH, BOX_HEIGHT);
- }
- else {
- pn.color(DarkGray);
- port->moveTo(xmin, ymax);
- port->lineTo(xmax, ymax);
- port->lineTo(xmax, ymin);
-
- port->moveTo(xmin + 1, ymax - 1);
- port->lineTo(xmax - 1, ymax - 1);
- port->lineTo(xmax - 1, ymin + 1);
-
- pn.color(WHITE);
- port->moveTo(xmax, ymin);
- port->lineTo(xmin, ymin);
- port->lineTo(xmin, ymax);
-
- rect.set(CenterDim, cinfo->getX(), cinfo->getY() + 1, BOX_WIDTH, BOX_HEIGHT);
- }
-
- port->usePen(NIL);
- port->useBrush(NIL);
-
- port->wrtText(cinfo->getName()->gets(), &rect, JustifyCenter);
- }
-
- boolean ClassTreeView::mouseDn(int mx, int my)
- /*
- Mouse button released in the class window
- */
- {
- ClassInfo *cinfo;
- boolean changed;
-
- if ((cinfo = pick(mx, my)) != 0) {
- aPort->open();
- changed = setCurrClass(cinfo, aPort);
- aPort->close();
-
- if (changed) {
- /* invoke callback method */
- if (client && selectMthd != NIL_METHOD) {
- client->perform(selectMthd);
- }
- }
- }
-
- return(TRUE);
- }
-
- ClassInfo *ClassTreeView::pick(int mx, int my)
- /*
- Test if point (mx, my) hits a class box.
- If so return a pointer to the ClassInfo box, else 0
- */
- {
- ClassInfo *cinfo;
- VRectangle rect;
-
- for (cinfo = firstClass; cinfo != 0; cinfo = cinfo->getNext()) {
- rect.set(CenterDim, cinfo->getX(), cinfo->getY(), BOX_WIDTH, BOX_HEIGHT);
- if (rect.pointIn(mx, my)) {
- return(cinfo);
- }
- }
-
- return(0);
- }
-
- boolean ClassTreeView::setCurrClass(ClassInfo *cinfo, VPort *port)
- /*
- Make 'cinfo' the selected class...
- Return TRUE if the current class changes
- */
- {
- ClassInfo *old = currClass;
- currClass = cinfo;
-
- if (old != currClass) {
- if (port && old) {
- /* repaint old box */
- drawClass(old, port);
- }
- if (port && currClass) {
- /* repaint new box */
- drawClass(currClass, port);
- }
-
- return(TRUE);
- }
-
- return(FALSE);
- }
-
- void ClassTreeView::uponClick(id clnt, method mthd)
- /*
- Attach a callback member to the treeview
- */
- {
- if (clnt) {
- client = clnt;
- }
- if (mthd) {
- selectMthd = mthd;
- }
- if (!clnt || mthd == NIL_METHOD) {
- client = NIL;
- selectMthd = NIL;
- }
- }
-
-